package com.javafactroy.kunlong.framework.generalthread;

import com.javafactroy.kunlong.base.utils.GeneralThreadPool;
import com.javafactroy.kunlong.client.feign.dto.ApiResult;
import com.javafactroy.kunlong.framework.generalthread.base.GeneralFutureTask;
import com.javafactroy.kunlong.framework.generalthread.iface.IgeneralRunner;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.*;

@Service
@Slf4j
public class GeneralThread<T> {

    public ApiResult<T> exec(IgeneralRunner<T> runner) throws InterruptedException, ExecutionException {

        CountDownLatch countDownLatch = new CountDownLatch(runner.getData().getThreadNum());
        List<Future<ApiResult<T>>> list = new ArrayList<>();
        runner.getData().split2Group().getGroupList().forEach(i -> {

            Future<ApiResult<T>> future = GeneralThreadPool.inst().submit(
                    new GeneralFutureTask(i, runner, countDownLatch));
            list.add(future);
        });
        countDownLatch.await(runner.getData().getThreadWaitMinutes(),TimeUnit.MINUTES);

        return merge(list);//mergeResult(list);
    }
    ApiResult<T> merge(List<Future<ApiResult<T>>> list) throws ExecutionException, InterruptedException {
        ApiResult<T> result = mergeResult(list);
        mergeResultList(result,list);
        return result;
    }
    ApiResult<T> mergeResult(List<Future<ApiResult<T>>> list) throws ExecutionException, InterruptedException {
        ApiResult<T> result = ApiResult.success();
        for (Future<ApiResult<T>> f : list) {
            ApiResult i = f.get();
            if (!i.getCode().equals(200)) {
                result = i;
            }
        }
        return result;
    }
    ApiResult<T> mergeResultList(ApiResult<T> result,List<Future<ApiResult<T>>> list) throws ExecutionException, InterruptedException {
        //ApiResult<T> result = ApiResult.success();
        for (Future<ApiResult<T>> resultFuture : list) {
            ApiResult<T> apiResult = resultFuture.get();
            if (!apiResult.getCode().equals(200)) {
                result.getDataList().add(apiResult.getData());
            }
        }
        return result;
    }

}
